from xml.parsers import expat
from element import Element

class Parser:
    def __init__(self):
        self.__parser = expat.ParserCreate()
        self.__parser.StartElementHandler = self.__start_element
        self.__parser.EndElementHandler = self.__end_element
        self.__parser.CharacterDataHandler = self.__char_data
        self.__buscando = False
        self.__nombre_buscar = ""
        self.__encontrado = False
        self.__elemento = Element()
        self.__vec_elementos = []
        self.__attrs = {}

    def __start_element(self, name, attrs):
        if self.__buscando:
            if name == self.__nombre_buscar:
                self.__encontrado = True
                self.__elemento.set_name(repr(name))
                self.__elemento.set_attributes(attrs)
            elif self.__encontrado:
                self.__buscando = False
                    
    def __end_element(self, name):
        if name == self.__nombre_buscar and self.__encontrado:
            self.__buscando = False        
        
    def __char_data(self, data):
        if self.__buscando and self.__encontrado:
            self.__elemento.set_text(data)
            self.__buscando = False
    
    ###
    # Utilizo cuando quiero buscar un elemento teniendo en cuenta sus atributos
    ###
    def __start_element_attributes(self, name, attrs):
        #print "se busca: " + str(self.__nombre_buscar) + " y ahora estoy en: " + str(name)
        if self.__buscando:
            if name == self.__nombre_buscar and attrs == self.__attrs:
                self.__encontrado = True
                self.__elemento.set_name(repr(name))
                self.__elemento.set_attributes(attrs)
            elif self.__encontrado:
                self.__buscando = False
    
    ###
    # Utilizo como funcion de parseo cuando lo que quiero encontrar son todos los hijos de un elemento
    ###
    def __start_element_childs(self, name, attrs):
        if name == self.__nombre_buscar:
            self.__encontre_padre = True
        elif self.__encontre_padre:            
            elem = Element()
            elem.set_name(name)
            elem.set_attributes(attrs)
            self.__vec_elementos.append(elem)
    
    ###
    # Utilizo como funcion de parseo cuando lo que quiero encontrar son todos los hijos de un elemento
    ###
    def __char_data_childs(self, data):
        if not self.__vec_elementos == []:
            elem = self.__vec_elementos.pop()
            #Solamente si todavia no guarde el texto lo guardo            
            if elem.get_text('str') == "":                
                elem.set_text(data)
            self.__vec_elementos.append(elem)
    
    ###
    # Utilizo como funcion de parseo cuando lo que quiero encontrar son todos los hijos de un elemento
    ###
    def __end_element_childs(self, name):
        if name == self.__nombre_buscar:
            self.__encontre_padre = False
    
    #Busca el elemento sin tener en cuenta sus atributos
    def find_element(self, elemento, xml):
        self.__buscando = True
        self.__nombre_buscar = elemento
        self.__encontrado = False
        self.__elemento.clear()
        self.parse(xml)
        #if self.__encontrado:
        #    print str(self.__elemento)
        return self.__elemento
    
    #Busca el elemento teniendo en cuenta los atributos del mismo
    def find_element_attribute(self, elemento, attrs, xml):
        #print "AHORA VOY A BUSCAR " + str(elemento)
        self.__buscando = True
        self.__nombre_buscar = elemento
        self.__attrs = attrs
        self.__encontrado = False
        self.__elemento.clear()
        self.__parser.StartElementHandler = self.__start_element_attributes
        self.parse(xml)
        #if self.__encontrado:
        #    print str(self.__elemento)
        return self.__elemento
    
    def find_child_element(self, padre, xml):
        self.__encontre_padre = False
        self.__nombre_buscar = padre
        #Cambio las funciones de parseo y utilizo unas especiales para buscar hijos de los elementos
        self.__parser.StartElementHandler = self.__start_element_childs
        self.__parser.EndElementHandler = self.__end_element_childs
        self.__parser.CharacterDataHandler = self.__char_data_childs
        self.parse(xml)        
        #for e in self.__vec_elementos:
        #    print str(e)
        return self.__vec_elementos
        
    def xml_has_element(self, elemento, xml):
        self.__buscando = True
        self.__nombre_buscar = elemento
        self.__encontrado = False
        self.parse(xml)
        return self.__encontrado
        
    def parse(self, xml):                
        if type(xml) == file:
            xml = xml.read()
        xml = unicode(xml,"latin-1").encode('iso-8859-1')
        try:
            self.__read_xml(xml)
        except Exception, e:
            print e
    
    def __read_xml(self, xml):
        self.__parser.Parse(xml,0)
    
    def close(self):
        self.__parser.Parse("", 1) 
        del self.__parser 

if __name__ == "__main__":
    v = []
    
    p = Parser()
    
    f = open("../../files/games.xml")
    
    v = p.find_child_element("games",f)
    
    p.close()
    